var html = `
<!--
[configStart]
{
  "ydui": true,
  "lazyload": "lazyload",
  "pageInfo": {
    "title": "参与申请",
    "keywords": "",
    "description": ""
  }
}
[configEnd]
-->

<script type="index">
var main = 1
console.log(main)
</script>

<script type="index">
var main = 1
console.log(main)
</script>

<script type="config">
  ({
    "ydui": true,
    "lazyload": "lazyload",
    "pageInfo": {
      "title": "参与申请",
      "keywords": "",
      "description": ""
    }
  })
</script>

<script type="config">
  ({
    "antdv": true,
    "pageInfo":{
      "title": "你好"
    }
  })
</script>


<template>
  <div class="active-join">

    <ul>
      <li v-for="(item,index) in mockData"
          :key="index"
          class="mod">
        <div class="mod-title">
          <h2 class="title">{{item.title}}</h2>
        </div>

        <div class="form-wap"
             v-for="(formItem,formIndex) in item.form"
             :key="index+'_'+formIndex">
          <component v-model="formData[formItem.name]"
                     :class="componentName[formItem.form_type].class"
                     :is="componentName[formItem.form_type].name"
                     :placeholder="'请输入'+formItem.label"
                     :type="formItem.type"
                     :maxlength="formItem.maxLength"
                     :max="formItem.maxLength"
                     :itemname="formItem.name"
                     :name="formItem.name"
                     @click.native="removeError($event,formItem.name)"
                     :on-blur="checkItem"
                     :show-success-icon="false"
                     :on-focus="removeError">
            <template v-if="formItem.form_type === 'radio'">
              <span>请选择{{formItem.label}}：</span>
              <yd-radio v-for="radioItem in formItem.list"
                        :key="radioItem.value"
                        :val="radioItem.value">
                {{radioItem.label}}
              </yd-radio>
            </template>
          </component>
          <div class="error-tips"
               v-show="error && error[formItem.name]">{{error[formItem.name]}}</div>
        </div>
      </li>
      <!-- <li class="mod">
        <div class="mod-title">
          <h2 class="title">联系资料</h2>
        </div>

        

        <yd-input class="form-item"
                  v-model="formData.phone"
                  type="tel"
                  :show-clear-icon="true"
                  placeholder="请输入联系电话"
                  :max="11"></yd-input>

        <yd-input class="form-item"
                  v-model="formData.wechat"
                  :show-clear-icon="true"
                  placeholder="请输入微信号"></yd-input>
      </li>

      <li class="mod">
        <div class="mod-title">
          <h2 class="title">申请理由</h2>
          <label class="sync-checkbox">
            <input type="checkbox"
                   v-model="sync"
                   value="true" />
            <span class="check-box"></span>
            <span>同步至活动留言区</span>
          </label>
        </div>

        <yd-textarea class="form-textarea-item"
                     placeholder="请说出你的理由哦~"
                     maxlength="200"
                     v-model="formData.reason"></yd-textarea>
      </li> -->
    </ul>

    <div class="mod-submit">
      <yd-button size="large"
                 type="primary"
                 :loading="loading"
                 loading-txt="数据保存中，请稍后"
                 @click.native="submitData">提交申请</yd-button>
    </div>
  </div>
</template>



<script>
import '../utils/rem.js'
const mockData = {
  section: [
    {
      title: "个人信息",
      form: [{
        form_type: 'input',
        type: 'text',
        label: '姓名',
        required: true,
        validate_type: 'hello',
        name: 'name'
      }, {
        form_type: 'radio',
        type: '',
        list: [{ value: '0', label: '男' }, { value: '1', label: '女' }],
        label: '性别',
        required: true,
        validate_type: '',
        name: 'sex'
      }, {
        form_type: 'input',
        type: 'text',
        label: '身份证号',
        required: true,
        validate_type: '',
        name: 'idcard'
      }]
    },
    {
      title: "联系方式",
      form: [{
        form_type: 'input',
        type: 'tel',
        label: '手机号',
        required: true,
        validate_type: 'phone',
        name: 'phone',
        maxLength: 11
      }, {
        form_type: 'input',
        type: 'email',
        label: '邮箱',
        required: true,
        validate_type: 'email',
        name: 'email'
      }, {
        form_type: 'input',
        type: 'text',
        label: 'QQ号',
        required: true,
        validate_type: '',
        name: 'qq'
      }, {
        form_type: 'input',
        type: 'text',
        label: '微信ID',
        required: true,
        validate_type: '',
        name: 'wechat'
      }, {
        form_type: 'input',
        type: 'text',
        label: '微博ID',
        required: true,
        validate_type: '',
        name: 'weibo'
      }, {
        form_type: 'input',
        type: 'text',
        label: '地址',
        required: true,
        validate_type: '',
        name: 'address'
      }]
    }, {
      title: "参与理由",
      form: [{
        form_type: 'textarea',
        type: 'text',
        label: '参与理由',
        required: true,
        validate_type: '',
        name: 'reason',
        maxLength: 200
      }]
    }
  ]
}
// 组件和后端字段映射名称和class名
const componentName = {
  input: {
    name: 'yd-input',
    class: ['form-item']
  },
  textarea: {
    name: 'yd-textarea',
    class: ['form-textarea-item']
  },
  radio: {
    name: 'yd-radio-group',
    class: ['form-radio-item']
  }
}

const validateRules = {
  phone: /^(?:(?:\+|00)86)?1[3-9]\d{9}$/,
  email: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
}
export default {
  name: 'Join',
  data () {
    return {
      componentName: componentName, // 组件和字段对应的配置
      error: {}, // 每条数据对应错误的信息
      // 模拟后端数据
      mockData: mockData.section,
      formData: {}, // 提交表单的数据
      rules: [], // 正则/其他规则验证的数据
      pk: '', // 活动ID
      sync: ['true'], // 存储是否同步
      loading: false,
    }
  },
  created () {
    this.pk = this.$apm.pageData.pk || ''
  },
  mounted () {
    this.initFormData()
  },
  methods: {
    // 初始化表单数据和验证规则
    initFormData () {
      var formData = {}
      var rules = {}
      this.mockData.forEach(item => {
        item.form.forEach((formItem) => {
          if (formItem.name) {
            formData[formItem.name] = '' // 添加formData默认字段 用于 v-model
            rules[formItem.name] = [] // 生成默认的规则数组

            let action = formItem.form_type === 'radio' ? '请选择' : '请输入'

            // 判断必填
            if (formItem.required) {
              rules[formItem.name].push({ required: true, message: action + formItem.label })
            }

            // 正则验证，前提是已经约定好正则
            if (formItem.validate_type && validateRules[formItem.validate_type]) {
              // 正则表达式，validator 作为方法名，传入val，使用正则匹配val。作用可见 checkFormItemError 方法
              rules[formItem.name].push({ validator: val => validateRules[formItem.validate_type].test(val), message: action + '正确的' + formItem.label })
            }
          }
        })
      })

      this.$set(this, 'formData', formData)
      this.rules = rules
    },

    // 提交数据
    submitData () {

      if (!this.pk) {
        this.$dialog.toast({
          mes: '活动不存在，请稍后重试',
          timeout: 2000,
          icon: 'error'
        });
        return false
      }

      var formData = this.formData
      var rules = this.rules
      var hasError = false

      // 标记出所有有错误的选项
      Object.keys(formData).reverse().forEach(name => {
        let { state, error } = this.checkFormItemError(rules[name], formData[name])
        if (state) {
          hasError = state
          this.$set(this.error, name, error)
          document.querySelector("[itemname=" + name + "]").classList.add('form-item-error')
        }
      })

      if (hasError) {
        // this.$dialog.toast({
        //   mes: message,
        //   timeout: 1500
        // });
      } else {
        this.loading = true
        formData.pk = this.pk
        this.$apm.fetch({
          url: '/interest/activity/join',
          method: 'POST',
          timeout: 30000,
          param: formData
        }).then(res => {
          this.loading = false
          this.$dialog.toast({
            mes: res.msg || '提交成功',
            timeout: 3000,
            icon: res.stat == '1' ? 'success' : 'error',
            callback: () => {
              if (res.stat == '1') {
                if (window.history.length >= 2) {
                  // 返回上一页
                  window.history.go(-1)
                } else {
                  // 跳转回活动详情
                  window.location.replace('/saas/activity/detail.html?pk=' + this.pk + '&&_app_id=' + this.$apm.pageData._app_id)
                }
              }
            }
          });
        }).catch(res => {
          this.loading = false
        })
      }
    },

    /**
     * 检验方法
     * @param {Array} rules 需要检验的规则
     * @param {Any} value  需要检验的值
     * @return {Object} {state,error} state:为true验证不通过 error:错误信息
     */
    checkFormItemError (rules, value) {
      let error = ''
      let state = rules.some(item => {
        if (item.required && (value === '' || !value)) {
          error = item.message
          return true
        } else if (item.validator && !item.validator(value)) {
          error = item.message
          return true
        }
      })
      return { state, error }
    },

    // 单击的时候，移除对应的错误样式
    removeError (e, name) {
      let itemName = name || e.target.name
      if (itemName) {
        this.$set(this.error, itemName, '')
        document.querySelector("[itemname=" + itemName + "]").classList.remove('form-item-error')
      }
    },

    // 检测表单某一项
    checkItem (e, name) {
      let itemName = name || e.target.name
      let { state, error } = this.checkFormItemError(this.rules[itemName], this.formData[itemName])
      if (state) {
        this.$set(this.error, itemName, error)
        document.querySelector("[itemname=" + itemName + "]").classList.add('form-item-error')
      } else {
        this.removeError(e, itemName)
      }
    }
  },
}
</script>

<style lang="less">
@import '~@common/assets/css/reset.less';

body {
  background-color: #fff !important;
}

.active-join {
  font-size: 0.8rem;
  .mod {
    padding: 0 0.75rem;
    .mod-title {
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: 2.5rem;
      .title {
        font-size: 0.9rem;
        font-weight: 700;
      }

      .sync-checkbox {
        display: flex;
        align-items: center;
        line-height: 1rem;

        .check-box {
          width: 1rem;
          height: 1rem;
          display: block;
          border-radius: 50%;
          border: 0.03rem solid #f2f2f2;
          margin-right: 0.25rem;
          transform: scale(0.8);
        }

        input[type='checkbox'] {
          display: none;
        }

        input[type='checkbox']:checked + .check-box {
          border-color: #f29834;
          position: relative;
          &::before {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 0.5rem;
            height: 0.5rem;
            background-color: #f29834;
            content: '';
            border-radius: 50%;
          }
        }
      }
    }

    .form-wap {
      & + .form-wap {
        margin-top: 0.75rem;
      }
    }

    .form-item {
      height: 2.5rem;
      border: 0.03rem solid #f2f2f2;
      border-radius: 0.5rem;
      padding: 0 0.5rem;
      width: 100%;
      &.form-item-error {
        border-color: #ff0000;
        color: #ff0000;
      }
    }
    .form-radio-item {
      &.form-item-error {
        color: #ff0000;
      }
    }

    .form-textarea-item {
      border: 0.03rem solid #f2f2f2;
      border-radius: 0.5rem;
      padding: 0.5rem;
      height: 5rem;
      textarea {
        line-height: 1.5;
        font-size: 0.8rem !important;
        height: 85% !important;
      }
      &.form-item-error {
        border: 0.03rem solid #ff0000;
        color: #ff0000;
      }
    }

    .error-tips {
      font-size: 0.3rem;
      color: #ff0000;
      margin-top: 0.25rem;
      text-align: right;
    }
  }

  .mod-submit {
    padding: 0.5rem;
    .yd-btn-block {
      height: 2rem !important;
    }
  }
}
</style>
`

// 其实原理应该很简单，因为 ? 也是贪婪匹配，并且只能匹配0到1个，
// 所以它会匹配到第一个的时候就结束了，从而阻止了 * 的匹配多个的贪婪。
// html.replace(/<script type="index">[\d\D]*?<\/script>/g, function () {
//   arguments[0]
//               .replace(/[\r\n]/g, '')
//               .replace(/ /g, '')
//               .replace(/\[configStart\]/, '')
//               .replace(/\[configEnd\]/, '')
// })

var main = html.match(/<script type="index">[\d\D]*?<\/script>/g)
var config = html.match(/<script type="config">[\d\D]*?<\/script>/g)

main.forEach((item, index) => {
  main[index] = item.replace(/<script type="index">/, '').replace(/<\/script>/, '')
})
console.log(main.join('\n'), 'main')

var allConfig = {}

config.forEach((item, index) => {
  let c = JSON.parse(
    item
      .replace(/<script type="config">/, '')
      .replace(/<\/script>/, '')
      .replace(/[\r\n]/g, '')
      .replace(/ /g, '')
      .replace(/\(\{/g, '{')
      .replace(/\}\)/g, '}')
  )

  allConfig = Object.assign({}, allConfig, c)
})

console.log(main.join('\r\n'), 'main')
console.log(allConfig, 'config')
